<template>
  <div>
    <!-- :disabled="isDisabled" -->
    <el-input :placeholder="placeholder"
      @focus="$emit('focus')"
      :maxlength="6"
      v-model="input">
      <div slot="suffix"
        :class="{'send-btn':1,disabled:isDisabled}"
        @click="handleClickCode">
        {{btnText}}
      </div>
    </el-input>
    <el-dialog :visible.sync="imgCaptchaVisible"
      top="105px"
      :close-on-click-modal="false"
      append-to-body
      custom-class="img-captcha-dialog dialog-offset"
      width="380px">
      <p class="title">图形验证码</p>
      <el-form ref="captchaForm"
        :model="form"
        onsubmit="return false"
        :rules="rules">
        <div class="img-wrap">
          <div class="img-box"
            v-if="!captcha || loading">
            <div class="el-image__error">{{loading?'加载中':'加载失败'}}</div>
          </div>

          <el-image :src="captcha"
            class="img-box"
            v-else></el-image>
          <div class="img-text">看不清?<el-button type="text"
              @click="refresh">换一张</el-button>
          </div>
        </div>
        <el-form-item prop="code"
          style="margin-bottom:0;">
          <el-input v-model="form.code"
            placeholder="输入上方图形验证码"
            maxlength="4"
            @keydown.enter.native="complete"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer"
        class="dialog-footer">
        <el-button type="primary"
          @click="complete"
          size="small">确 定</el-button>
        <el-button @click="imgCaptchaVisible = false"
          size="small">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script type="text/javascript">
import { sendSms, getCodeImg } from '@/api/login'
export default {
  name: 'CodeInput',
  props: {
    value: null,
    disabled: Boolean,
    phoneNumber: null,
    placeholder: {
      type: String,
      default: '请输入验证码'
    }
  },
  data () {
    return {
      imgCaptchaVisible: false,
      handleCount: 0,
      sending: false,
      timer: 0,
      captcha: null,
      captchaID: null,
      loading: true,
      form: {
        code: ''
      },
      rules: {
        code: [
          { require: true, message: '请输入图形验证码', trigger: ['change'] }
        ]
      }
    }
  },
  computed: {
    input: {
      get () {
        return this.value
      },
      set (val) {
        this.$emit('update:value', val)
      }
    },
    isDisabled () {
      return (this.disabled === true || this.timer || this.sending)
    },
    btnText () {
      if (this.sending) {
        return '发送中'
      }
      if (this.timer) {
        return '重新发送（' + this.timer + 's）'
      }
      if (this.handleCount) {
        return '重新发送'
      }
      return '获取验证码'
    }
  },
  methods: {
    handleClickCode () {
      if (this.isDisabled) return
      this.sendSms(true)
    },
    onShowCaptcha () {
      this.imgCaptchaVisible = true
      this.resetFields()
    },
    refresh () {
      this.loading = true
      this.captcha = ''
      getCodeImg({ offset: 169 }).then(res => {
        const data = res.data || {}
        this.$nextTick(() => {
          this.captcha = data.captcha
        })
        this.captchaID = data.id
      }).finally(e => {
        this.loading = false
      })
    },
    complete () {
      if (!this.form.code) {
        this.showValidateErrMsg({ message: '请输入图片验证码' })
      } else if (/^\w{4}$/.test(this.form.code)) {
        this.sendSms()
      } else {
        this.showValidateErrMsg({ message: '图片验证码错误，请重新输入' })
      }
    },
    /**
     * 发送手机验证码
     * @param {Boolean} noCaptcha
     */
    sendSms (noCaptcha) {
      const params = {
        'phoneNumber': this.phoneNumber,
        'type': 'phone',
        'eMail': ''
      }
      if (!noCaptcha) {
        params.captcha = this.form.code
        params.captchaID = this.captchaID
      }
      this.sending = true
      sendSms(params, { offset: 169 }).then((res = {}) => {
        this.sending = false
        res.data = res.data || {}
        if (res.data.Verify === false) {
          this.refresh()
          this.showValidateErrMsg({ message: '图片验证码错误，请重新输入' })
          return
        }
        this.imgCaptchaVisible = false
        this.showValidateErrMsg({ message: '验证码已发送至您的手机', offset: 169 })
        this.$emit('changeCodeID', res.data.ID)
        this.handleCount++
        this.timer = 60
        this.timerId = setInterval(() => {
          this.timer--
          if (this.timer <= 0) {
            clearInterval(this.timerId)
            this.timerId = null
            this.timer = 0
          }
        }, 1000)
      }).catch(e => {
        this.sending = false
        this.refresh()
        if (e && e.code === 451) {
          this.onShowCaptcha()
        }
      })
    },
    resetFields () {
      this.$refs.captchaForm && this.$refs.captchaForm.resetFields()
    },
    showValidateErrMsg (opt) {
      this.$PsMessage(opt)
    }
  }
}
</script>

<style lang="scss" scoped>
@import "@/theme/common/var";
.send-btn {
  font-size: 14px;
  font-weight: 400;
  color: rgba($color: #fff, $alpha: 0.3);
  margin-right: 10px;
  user-select: none;
  cursor: no-drop;
  &:not(.disabled) {
    cursor: pointer;
    color: $--color-primary;
    &:hover {
      opacity: 0.8;
    }
  }
}
.title {
  font-size: 18px;
  font-weight: 400;
  text-align: center;
  margin-bottom: 20px;
}
.img {
  &-wrap {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    margin-bottom: 15px;
  }
  &-box {
    width: 200px;
    height: 80px;
  }
  &-text {
    .el-button {
      padding: 0;
    }
  }
}
.dialog-footer {
  .el-button {
    width: 80px;
  }
}
</style>
<style lang="scss">
.img-captcha-dialog {
  .el-dialog__body {
    padding: 0 34px 20px;
  }
}
</style>
